# -*- coding:utf-8 -*-
"""
@Created on : 2022/4/22 22:02
@Author: binkuolo
@Des: app运行时文件
"""

from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.sessions import SessionMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from tortoise.exceptions import DoesNotExist, IntegrityError, OperationalError, ValidationError
from fastapi_pagination import add_pagination

from api.api import api_router

from config import settings
from core import Exception, Events

# app主要配置
application = FastAPI(
    debug=settings.APP_DEBUG,
    title=settings.APP_TITLE,
    description=settings.APP_DESCRIPTION,
    version=settings.APP_VERSION,
    docs_url=settings.APP_DOCS_URL,
    redoc_url=settings.APP_REDOC_URL,
)
# 路由
application.include_router(api_router)

# 静态资源目录
application.mount("/files", StaticFiles(directory='files'), name="files")
application.mount('/', StaticFiles(directory=settings.STATIC_DIR), name="static")
application.state.views = Jinja2Templates(directory=settings.TEMPLATE_DIR)


# 事件监听
Events.startup_event(application)
Events.shutdown_event(application)

# 异常错误处理
application.add_exception_handler(HTTPException, Exception.http_error_handler)
application.add_exception_handler(RequestValidationError, Exception.http422_error_handler)
application.add_exception_handler(Exception.UnicornException, Exception.unicorn_exception_handler)
application.add_exception_handler(DoesNotExist, Exception.mysql_does_not_exist)
application.add_exception_handler(IntegrityError, Exception.mysql_integrity_error)
application.add_exception_handler(ValidationError, Exception.mysql_validation_error)
application.add_exception_handler(OperationalError, Exception.mysql_operational_error)

# 中间件
# 跨域请求配置
application.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=settings.CORS_ALLOW_CREDENTIALS,
    allow_methods=settings.CORS_ALLOW_METHODS,
    allow_headers=settings.CORS_ALLOW_HEADERS,
)
# sessions配置
application.add_middleware(
    SessionMiddleware,
    secret_key=settings.SECRET_KEY,
    session_cookie=settings.SESSION_COOKIE,
    max_age=settings.SESSION_MAX_AGE
)
# 分页配置
add_pagination(application)
app = application

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app='main:app', host=settings.APP_HOST, port=settings.APP_PORT, reload=True)
